﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace app
{
    public class DrawImage : INotifyPropertyChanged
    {
        ImageSource imgSource;
        private WriteableBitmap m_WriteableBitmap;
        PixelFormat pixelFormat;

        Int32Rect rect;
        int stride;

        private int width;
        private int height;
        private int bytesperpixel;
        private byte[] imgData;
        
        //public WriteableBitmap(
        //    int pixelWidth,
        //    int pixelHeight,
        //    double dpiX,
        //    double dpiY,
        //    PixelFormat pixelFormat,
        //    BitmapPalette palette
        //)   

        public DrawImage()
        { 
        }

        public DrawImage(int width, int height, int bytesperpixel)
        {
            this.width = width;
            this.height = height;
            this.bytesperpixel = bytesperpixel;
        }

        public void initialize(int width, int height, int bytesperpixel)
        {
            this.width = width;                                         //넓이
            this.height = height;                                       //높이
            this.bytesperpixel = bytesperpixel;                         //채널 byte 크기
            stride = width * bytesperpixel;                             //가로 픽셀
            imgData = new byte[width * height * bytesperpixel];  //이미지 데이터 할당

            switch (bytesperpixel)
            {
                case 1:
                    this.pixelFormat = PixelFormats.Gray8;              //1byte 그레이스케일
                    //MessageBox.Show("1byte GrayScale 채널");
                    break;
                case 3:
                    this.pixelFormat = PixelFormats.Rgb24;              //3byte RGB
                    //MessageBox.Show("3byte RGB 채널");
                    break;
                case 4:
                    this.pixelFormat = PixelFormats.Pbgra32;            //4byte BGRA (BGR + Alpha Channel)
                    //MessageBox.Show("4byte BGRA 채널");
                    break;
            }

            m_WriteableBitmap = new WriteableBitmap(width, height, 96, 96, pixelFormat, null);
            rect = new Int32Rect(0, 0, width, height);
        }

        internal void CreateGrayImageData(int width, int height, byte[] imgData)     // 중간에 가로로 한줄을 검은색으로 긋는 데이터
        {
            Random ran = new Random();

            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    //imgData[row * width + col] = Convert.ToInt32(ranNum);

                    imgData[row * width + col] = (byte)ran.Next(0, 255);

                    //imgdata[row * stride + col * 4 + 0] = 0;  // BGRA일 때 예제에서 가져왔음.
                    //imgdata[row * stride + col * 4 + 1] = Convert.ToByte((1 - (col / (float)width)) * 0xff);
                    //imgdata[row * stride + col * 4 + 2] = Convert.ToByte((col / (float)width) * 0xff);
                    //imgdata[row * stride + col * 4 + 3] = Convert.ToByte((row / (float)height) * 0xff);
                }
            }
        }

        internal void CreateColorImageData(int width, int height, byte[] imgData)
        {
            Random ran = new Random();
            
            //알파는 FF로 고정

            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < height; col++)
                {
                    imgData[row * stride + col * 4 + 0] = (byte)ran.Next(0, 255);  // B
                    imgData[row * stride + col * 4 + 1] = (byte)ran.Next(0, 255);  // G
                    imgData[row * stride + col * 4 + 2] = (byte)ran.Next(0, 255);  // R
                    imgData[row * stride + col * 4 + 3] = 0xFF;                     // A는 0xFF로 고정
                }
            }
        }

        internal void ImageDataToBitmap()
        {
            m_WriteableBitmap.WritePixels(rect, imgData, stride, 0);
        }

        internal void WriteableBitmapToImageSource()
        {
            ImgSource = m_WriteableBitmap;
        }

        public int Width
        {   get { return width; }
            set { width = value; }  }
        public int Height
        {   get { return height; }
            set { height = value; } }
        public byte[] ImgData
        {   get { return imgData; }
            set { imgData = value; }}
        public ImageSource ImgSource
        {
            get { return imgSource; }
            set { imgSource = value; OnPropertyChanged("ImgSource"); }
        }
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
